<?php
namespace Plu\Library\Services\Utility;

use DateTime,
    DateTimeZone,

    Plu\Library\Services\ServiceBase;

class DateTimeService extends ServiceBase {
	public static $niceFormat = '%a, %b %eS %Y, %H:%M';
	public static $niceShortFormat = '%B %d, %H:%M';

	public static function duration($durationInSeconds) {
		$duration = '';
		$hours = floor($durationInSeconds / 3600);
		$durationInSeconds = $durationInSeconds - $hours * 3600;
		$minutes = floor($durationInSeconds / 60);
		$seconds = $durationInSeconds - $minutes * 60;
		if ($hours > 0) {
			$duration .= sprintf("%02d:", $hours);
		}
		$duration .= sprintf("%02d:%02d", $minutes, $seconds);

		return $duration;
	}

	public static function fromString($dateString, $timezone = null) {
		if (empty($dateString)) {
			return false;
		}

		if (is_int($dateString) || is_numeric($dateString)) {
			$date = intval($dateString);
		} elseif ($dateString instanceof DateTime && $dateString->getTimezone()->getName() != date_default_timezone_get()) {
			$clone = clone $dateString;
			$clone->setTimezone(new DateTimeZone(date_default_timezone_get()));
			$date = (int)$clone->format('U') + $clone->getOffset();
		} elseif ($dateString instanceof DateTime) {
			$date = (int)$dateString->format('U');
		} else {
			$date = strtotime($dateString);
		}

		if ($date === -1 || empty($date)) {
			return false;
		}

		if ($timezone !== null) {
			return self::convert($date, $timezone);
		}

		return $date;
	}

	/**
	 * 是否是今天？
	 */
	public static function isToday($dateString, $timezone = null) {
		$timestamp = self::fromString($dateString, $timezone);
		$now = self::fromString('now', $timezone);

		return date('Y-m-d', $timestamp) == date('Y-m-d', $now);
	}

	/**
	 * 是否是明日
	 */
	public static function isTomorrow($dateString, $timezone = null) {
		$timestamp = self::fromString($dateString, $timezone);

		return date('Y-m-d', $timestamp) == date('Y-m-d', strtotime('tomorrow'));
	}

	/**
	 * 是否是后天
	 */
	public static function isBermorgen($dateString, $timezone = null) {
		$timestamp = self::fromString($dateString, $timezone);

		return date('Y-m-d', $timestamp) == date('Y-m-d', strtotime('+2 day'));
	}

	/**
	 * Time from now
	 */
	public static function timeago($dateTime, $options = array()) {
		$timezone = null; //时间区域
		$format = 'j/n/y'; //时间默认格式
		$end = "+1 month"; //默认不使用timeago的时间
		$relativeString = '%s前';//相对时间
		$absoluteString = '%s'; // 绝对时间
		//精准度
		$accuracy = array(
			'year'   => "day",
			"month"  => "day",
			"week"   => 'day',
			'day'    => "hour",
			"hour"   => "minute",
			"minute" => "minute",
			"second" => "second"
		);

		if (is_array($options)) {
			if (isset($options['timezone'])) {
				$timezone = $options['timezone'];
			} elseif (isset($options['userOffset'])) {
				$timezone = $options['userOffset'];
			}

			if (isset($options['accuracy'])) {
				if (is_array($options['accuracy'])) {
					$accuracy = array_merge($accuracy, $options['accuracy']);
				} else {
					foreach ($accuracy as $key => $level) {
						$accuracy[$key] = $options['accuracy'];
					}
				}
			}

			if (isset($options['format'])) {
				$format = $options['format'];
			}
			if (isset($options['end'])) {
				$end = $options['end'];
			}
			if (isset($options['relativeString'])) {
				$relativeString = $options['relativeString'];
				unset($options['relativeString']);
			}
			if (isset($options['absoluteString'])) {
				$absoluteString = $options['absoluteString'];
				unset($options['absoluteString']);
			}
			unset($options['end'], $options['format']);
		} else {
			$format = $options;
		}

		$now = self::fromString(time(), $timezone);
		$inSeconds = self::fromString($dateTime, $timezone);
		$backwards = ($inSeconds > $now);

		$futureTime = $now;
		$pastTime = $inSeconds;

		if ($backwards) {
			$futureTime = $inSeconds;
			$pastTime = $now;

		}

		$diff = $futureTime - $pastTime;

		if (!$diff) {
			return '刚刚';
		}

		//if ($diff > abs($now - self::fromString($end))) {
		//      return sprintf($absoluteString, date($format, $inSeconds));
		//}

		//7 days
		if ($diff >= 604800) {
			list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime));

			list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime));
			$years = $months = $weeks = $days = $hours = $minutes = $seconds = 0;

			$years = $future['Y'] - $past['Y'];
			$months = $future['m'] + ((12 * $years) - $past['m']);

			if ($months >= 12) {
				$years = floor($months / 12);
				$months = $months - ($years * 12);
			}
			if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] === 1) {
				$years--;
			}

			if ($future['d'] >= $past['d']) {
				$days = $future['d'] - $past['d'];
			} else {
				$daysInPastMonth = date('t', $pastTime);
				$daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y']));

				if (!$backwards) {
					$days = ($daysInPastMonth - $past['d']) + $future['d'];
				} else {
					$days = ($daysInFutureMonth - $past['d']) + $future['d'];
				}

				if ($future['m'] != $past['m']) {
					$months--;
				}
			}

			if (!$months && $years >= 1 && $diff < ($years * 31536000)) {
				$months = 11;
				$years--;
			}

			if ($months >= 12) {
				$years = $years + 1;
				$months = $months - 12;
			}

			if ($days >= 7) {
				$weeks = floor($days / 7);
				$days = $days - ($weeks * 7);
			}
		} else {
			$years = $months = $weeks = 0;
			$days = floor($diff / 86400);

			$diff = $diff - ($days * 86400);

			$hours = floor($diff / 3600);
			$diff = $diff - ($hours * 3600);

			$minutes = floor($diff / 60);
			$diff = $diff - ($minutes * 60);

			$seconds = $diff;
		}

		$fWord = $accuracy['second'];

		if ($years > 0) {
			$fWord = $accuracy['year'];
		} elseif (abs($months) > 0) {
			$fWord = $accuracy['month'];
		} elseif (abs($weeks) > 0) {
			$fWord = $accuracy['week'];
		} elseif (abs($days) > 0) {
			$fWord = $accuracy['day'];
		} elseif (abs($hours) > 0) {
			$fWord = $accuracy['hour'];
		} elseif (abs($minutes) > 0) {
			$fWord = $accuracy['minute'];
		}

		$fNum = str_replace(array('year', 'month', 'week', 'day', 'hour', 'minute', 'second'), array(1, 2, 3, 4, 5, 6, 7), $fWord);

		//只显示单个时间
		$relativeDate = '';
		if ($fNum >= 1 && $years > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d年', $years);
		}
		elseif ($fNum >= 2 && $months > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d月', $months);
		}
		elseif ($fNum >= 3 && $weeks > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d周', $weeks);
		}
		elseif ($fNum >= 4 && $days > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d天', $days);
		}
		elseif ($fNum >= 5 && $hours > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d小时', $hours);
		}
		elseif ($fNum >= 6 && $minutes > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d分钟', $minutes);
		}
		elseif ($fNum >= 7 && $seconds > 0) {
			$relativeDate .= ($relativeDate ? ', ' : '') . sprintf('%d秒', $seconds);
		}

		if (!$backwards && $relativeDate) {
			return sprintf($relativeString, $relativeDate);
		}

		if (!$backwards) {
			$aboutAgo = array(
				'second' => '约1秒前',
				'minute' => '约1分钟前',
				'hour'   => '约1小时前',
				'day'    => '约1天前',
				'week'   => '约1周前',
				'year'   => '约1年前'
			);

			return $aboutAgo[$fWord];
		}

		// When time is to come
		if (!$relativeDate) {
			$aboutIn = array(
				'second' => '约1秒后',
				'minute' => '约1秒前',
				'hour'   => '约1小时后',
				'day'    => '约1天后',
				'week'   => '约1周后',
				'year'   => '约1年后'
			);

			return $aboutIn[$fWord];
		}

		return $relativeDate;
	}


	public static function nice($dateString = null, $timezone = null, $format = null) {
		if (!$dateString) {
			$dateString = time();
		}
		$date = self::fromString($dateString, $timezone);

		if (!$format) {
			$format = self::$niceFormat;
		}

		return date($format, $date);
	}

	public static function niceShort($dateString = null, $timezone = null) {
		if (!$dateString) {
			$dateString = time();
		}

		$date = self::fromString($dateString, $timezone);

	}
}
?>
